local handle_manager = handle_manager_class:create()
local ms = 256
local sign = "sync_content"
local cli, ser, tb1, tb2 = {}, {}, {}, {}
local sync_content = {}
setmetatable(sync_content, sync_content)
sync_content.perfixs = {}
sync_content.alltriggers = {}
sync_content.allacts = setmetatable({}, {__mode = 'kv'})
ac.sync_content = sync_content

function cli.req(name, content)
    local time = os.time()
    local map = tb1[name] or { }
    local obj = { name = name, time = time, data = { }, }
    for i=1,math.ceil(#content / ms) do 
        obj.data[i] = content:sub((i-1) * ms + 1, i * ms)
    end 
    map[time] = obj 
    tb1[name] = map
    return obj 
end 

function ser.res(name)
    local obj = { name = name, data = { }, }
    tb2[name] = obj
    return obj 
end 

function cli.on_message(name, data)
    local map = tb1[name]
    if not map then return end;
    local time, code = table.unpack(data)
    local req = map[time]
    if not req then return end;
    if req.timer then 
        req.timer:remove()
    end 
    if code >= 1 then 
        cli.send_message(name, {time, code, req.data[code]})
        req.timer = ac.wait(10 * 1000, function() 
            map[time] = nil 
        end)
    else 
        map[time] = nil 
    end 
end 

function cli.send_message(name, data)
    local map = tb2[name]
    if not map then return end;
    ac.sync(sign, name, data )
end 

function ser.on_message(player, name, data)
    local res = tb2[name]
    if not res then return end;
    local pid = player:get_id() 
    local time, code, str = table.unpack(data)
    local meta = ("%d|%d"):format(pid, time )
    local buff = res.data[meta]
    if not buff then 
        buff = { }
        res.data[meta] = buff
    end
    buff[code] = str
    if code == 1 then 
        sync_content:notify(name, player, table.concat(buff))
        ser.send_message(player, name, {time, 0})
        res.data[meta] = nil
    else 
        ser.send_message(player, name, {time, code - 1})
    end 
end 

function ser.send_message(player, name, data)
    if player:is_self() then 
        cli.on_message(name, data)
    end 
end 

ac.sync:on (sign) (function (_, player, name, data)
    ser.on_message(player, name, data)
end)

---全局事件回调
function sync_content:notify(name, ...)
    local trigger = sync_content.alltriggers[name]
    if not trigger then return end
    for i = #trigger.actors, 1, -1 do 
        trigger.actors[i]:execute(...)
    end
end

function sync_content:register(name)
    local trigger = sync_content.alltriggers[name]
    if not trigger then
        trigger = ac.trigger.create(name)
        trigger.remove = function(t)
            for i = #trigger.actors, 1, -1 do 
                local act = trigger.actors[i]
                act:remove()
                sync_content.allacts[act] = nil
            end 
            sync_content.alltriggers[name] = nil
        end
        sync_content.alltriggers[name] = trigger
        local perfix = handle_manager:allocate()
        sync_content.perfixs[perfix] = name 
        sync_content.perfixs[name] = perfix
        ser.res(name)
    end 
    return function (func)
        local act = trigger:add_actor(func)
        act.key = "同步长串字符串事件>" .. name
        sync_content.allacts[act] = true
        return act
    end
end

function sync_content:__call(name, content)
    local perfix = sync_content.perfixs[name]
    if not perfix then 
        return end
    if content:find('%(') or content:find("%)") then
        print("不允许有括号!")
        return
    end
    local req = cli.req(name, content)
    local time = req.time
    local code = #req.data
    local data = req.data[code]
    cli.send_message(name, {time, code, data})
    req.timer = ac.wait(10 * 1000, function() 
        tb1[name][time] = nil 
    end)
end

sync_content.on     = sync_content.register
sync_content.event  = sync_content.register

return sync_content